クライアントのホスト名が重複しているとNFS v4でAmazon FSx for NetApp ONTAPのボリュームをマウントできない件
クライアントのホスト名が重複しているとマウントできないぞ
こんにちは、のんピ(@non____97)です。
皆さんは同じホスト名のクライアントからNFS v4でAmazon FSx for NetApp ONTAP(以降FSx for ONTAP)のボリュームをマウントしたいと思ったことはありますか? 私はあります。
例えば、EC2インスタンスをAuto Scalingさせて、複数のEC2インスタンスからFSx for ONTAP内のファイルにアクセスしたい場合があると思います。
その際、EC2インスタンスのホスト名が同じだと、2台目以降のEC2インスタンスはNFS v4でFSx for ONTAPのボリュームをマウントできないということをみなさんご存知でしょうか。
ということで、今回はその原因と対処方法を紹介します。
いきなりまとめ
- クライアントのホスト名が重複しているとNFS v4でAmazon FSx for NetApp ONTAPのボリュームをマウントできない
- NFS v4ではホスト名をクライアントIDとして使用する
- クライアントIDは一意である必要がある
- 回避策は以下2つ
- ホスト名の変更
nfs4_unique_id
の設定
検証の環境
説明するにあたって検証環境を用意します。
検証の環境は以下の通りです。
EC2インスタンス B以外は、AWS CDKで各種リソースをデプロイします。使用したコードは以下リポジトリに保存しています。
EC2インスタンス AからNFS v4でFSx for ONTAPのボリュームにマウントできているか確認
それではEC2インスタンス Aにログインして、NFS v4でFSx for ONTAPのボリュームにマウントできているかを確認します。
# ホスト名の確認 $ hostname ec2-instance.corp.non-97.net # IPアドレスの確認 $ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000 link/ether 0e:84:4c:2f:e6:3b brd ff:ff:ff:ff:ff:ff inet 10.0.1.10/28 brd 10.0.1.15 scope global dynamic eth0 valid_lft 3557sec preferred_lft 3557sec inet6 fe80::c84:4cff:fe2f:e63b/64 scope link valid_lft forever preferred_lft forever # /etc/fstab の設定確認 $ cat /etc/fstab # UUID=11ea48e5-4a29-4c1e-bb12-8138651b1870 / xfs defaults,noatime 1 1 svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs /mnt/fsx nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,_netdev 0 0 # FSx for ONTAPのボリュームをNFSでマウントしているか確認 $ df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 471M 0 471M 0% /dev tmpfs tmpfs 479M 0 479M 0% /dev/shm tmpfs tmpfs 479M 352K 478M 1% /run tmpfs tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/nvme0n1p1 xfs 8.0G 1.6G 6.5G 20% / svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs nfs4 973M 320K 973M 1% /mnt/fsx # NFS v4.1でマウントしていることを確認 $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime) svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs on /mnt/fsx type nfs4 (rw,relatime,vers=4.1,rsize=65536,wsize=65536,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.1.10,local_lock=none,addr=10.0.1.20,_netdev)
OSのホスト名がec2-instance.corp.non-97.net
で、NFS v4.1でFSx for ONTAPの/nfs
を/mnt/nfs
にマウントできていることを確認できました。
EC2インスタンス BからNFS v4でFSx for ONTAPのボリュームにマウントできているか確認
次に、EC2インスタンス BからNFS v4でFSx for ONTAPのボリュームをマウントできているか確認します。
EC2インスタンス AのAMIを取得して、そのAMIを使ってEC2インスタンス Bを立てます。
EC2インスタンス B作成後、ログインしてFSx for ONTAPのボリュームをマウントできているかを確認します。
# ホスト名がEC2インスタンス Aと同じであることを確認 $ hostname ec2-instance.corp.non-97.net # IPアドレスの確認 $ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000 link/ether 0e:2a:5c:c8:1e:51 brd ff:ff:ff:ff:ff:ff inet 10.0.1.13/28 brd 10.0.1.15 scope global dynamic eth0 valid_lft 3508sec preferred_lft 3508sec inet6 fe80::c2a:5cff:fec8:1e51/64 scope link valid_lft forever preferred_lft forever # FSx for ONTAPのボリュームをNFSでマウントしているか確認 $ df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 471M 0 471M 0% /dev tmpfs tmpfs 479M 0 479M 0% /dev/shm tmpfs tmpfs 479M 348K 478M 1% /run tmpfs tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/nvme0n1p1 xfs 8.0G 1.6G 6.5G 20% / $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
EC2インスタンス BではFSx for ONTAPのボリュームをNFSでマウントできていないようです。
/etc/fstab
の設定を使用して手動でマウントしようとしても拒否されてしまいました。
$ sudo mount -a mount.nfs4: Operation not permitted
EC2インスタンス AでアンマウントしたするとEC2インスタンス Bからマウントできるか確認
次に、EC2インスタンス AでアンマウントするとEC2インスタンス Bからマウントできるか確認してみましょう
EC2インスタンス AでFSx for ONTAPのボリュームをアンマウントします。
# EC2インスタンス AでFSx for ONTAPのボリュームをアンマウント $ sudo umount /mnt/fsx # アンマウントされたことを確認 $ df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 471M 0 471M 0% /dev tmpfs tmpfs 479M 0 479M 0% /dev/shm tmpfs tmpfs 479M 404K 478M 1% /run tmpfs tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/nvme0n1p1 xfs 8.0G 1.6G 6.5G 20% / tmpfs tmpfs 96M 0 96M 0% /run/user/0 $ mount |grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
次にEC2インスタンス BからFSx for ONTAPのボリュームをマウントします。
# EC2インスタンスからFSx for ONTAPのボリュームをマウント $ sudo mount -a # NFS v4でマウントできたことを確認 $ df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 471M 0 471M 0% /dev tmpfs tmpfs 479M 0 479M 0% /dev/shm tmpfs tmpfs 479M 408K 478M 1% /run tmpfs tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/nvme0n1p1 xfs 8.0G 1.6G 6.5G 20% / tmpfs tmpfs 96M 0 96M 0% /run/user/0 svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs nfs4 973M 384K 973M 1% /mnt/fsx # mount コマンドからも確認 $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime) svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs on /mnt/fsx type nfs4 (rw,relatime,vers=4.1,rsize=65536,wsize=65536,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.1.13,local_lock=none,addr=10.0.1.20,_netdev)
EC2インスタンス Bからもマウントできました。
なぜ同じホスト名だとNFSでマウントにできないのか
同じホスト名だとNFSでマウントにできないのかという原因は、NFS v4の仕様にあります。
NFS v4のRFCであるRFC 7530 - Network File System (NFS) Version 4 Protocolを確認します。
その中に以下のような記載があります。
9.1.1. Client ID
For each LOCK request, the client must identify itself to the server.This is done in such a way as to allow for correct lock identification and crash recovery.
. . (中略) . .
There are several considerations for how the client generates the id string:
The string should be unique so that multiple clients do not present the same string. The consequences of two clients presenting the same string range from one client getting an error to one client having its leased state abruptly and unexpectedly canceled.
要するに、ロックの識別やクラッシュからの回復のために、NFSサーバーがクライアントを一意に識別するためのIDが必要とのことです。
次に、NetApp ONTAPのNFSのプラクティスが記載されているドキュメントを確認してみます。
以下のような記載がありました。
Workaround #3: Change the client name used with NFSv4.x mounts
By default, NFSv4.x uses the client’s host name for the client ID value when mounting to the NFS server.
どうやらNFS v4ではホスト名をクライアントIDとして使用するようですね。
そのため、ホスト名が重複している場合はNFS v4でマウントできないようです。
試しに、EC2インスタンス Aから手動でNFSのバージョンを指定せずにマウントしてみます。すると、NFS v3でマウントすることができました。
$ sudo mount -t nfs svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs /mnt/fsx $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime) svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs on /mnt/fsx type nfs (rw,relatime,vers=3,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=10.0.1.20,mountvers=3,mountport=635,mountproto=udp,local_lock=none,addr=10.0.1.20)
回避策
回避策を考えます。
一番簡単な方法はホスト名の変更です。
ホスト名をクライアントIDとして使用するので、ホスト名を[ホスト名]_[ランダムな文字列]
としてしまえば、クライアントIDの重複を回避できます。
2つ目がnfs4_unique_id
の設定です。
nfs4_unique_id
に指定した文字列はNFSのクライアントIDとして動作します。
The nfs.nfs4_unique_id boot parameter specifies a unique string that can be used instead of a system’s node name when an NFS client identifies itself to a server. Thus, if the system’s node name is not unique, or it changes, its nfs.nfs4_unique_id stays the same, preventing collision with other clients or loss of state during NFS reboot recovery or transparent state migration.
一意な文字列をnfs4_unique_id
に指定してあげればホスト名を変更する必要がありません。
nfs4_unique_id
に設定するする文字列は一意であればなんでもよさそうです。
Given the above considerations, an example of a well-generated id string is one that includes:
- The server's network address.
- The client's network address.
- For a user-level NFSv4 client, it should contain additional information to distinguish the client from other user-level clients running on the same host, such as a universally unique identifier (UUID).
- Additional information that tends to be unique, such as one or more of:
- The client machine's serial number (for privacy reasons, it is best to perform some one-way function on the serial number).
- A MAC address (for privacy reasons, it is best to perform some one-way function on the MAC address).
- The timestamp of when the NFSv4 software was first installed on the client (though this is subject to the previously mentioned caution about using information that is stored in a file, because the file might only be accessible over NFSv4).
- A true random number. However, since this number ought to be the same between client incarnations, this shares the same problem as that of using the timestamp of the software installation.
nfs4_unique_id を設定してマウント
それではnfs4_unique_id
を設定してマウントしてみます。
まず、デフォルトのnfs4_unique_id
の確認です。
カーネルモジュールのパラメータを確認することになるので、sysfsutils
をインストールします。
$ sudo yum install sysfsutils -y Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package sysfsutils.x86_64 0:2.1.0-16.amzn2.0.2 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================================= Package Arch Version Repository Size ============================================================================================================================================= Installing: sysfsutils x86_64 2.1.0-16.amzn2.0.2 amzn2-core 41 k Transaction Summary ============================================================================================================================================= Install 1 Package Total download size: 41 k Installed size: 119 k Downloading packages: sysfsutils-2.1.0-16.amzn2.0.2.x86_64.rpm | 41 kB 00:00:01 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : sysfsutils-2.1.0-16.amzn2.0.2.x86_64 1/1 Verifying : sysfsutils-2.1.0-16.amzn2.0.2.x86_64 1/1 Installed: sysfsutils.x86_64 0:2.1.0-16.amzn2.0.2 Complete!
インストール後、nfs4_unique_id
を確認します。
$ sudo systool -v -m nfs | grep -i nfs4_unique nfs4_unique_id = ""
nfs4_unique_id
は何も指定されていないようですね。
ランダムな文字列をnfs4_unique_id
にしてOSを再起動させます。
# 設定ファイルがあるか確認する $ ls -l /etc/modprobe.d/nfsclient.conf ls: cannot access /etc/modprobe.d/nfsclient.conf: No such file or directory # ランダムな文字列を nfs4_unique_id に指定 $ nfs4_unique_id=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9!@#$%^&*()_+-=[]{}<>?' | fold -w 32 | head -n 1) $ echo options nfs nfs4_unique_id="$nfs4_unique_id" | sudo tee -a /etc/modprobe.d/nfsclient.conf options nfs nfs4_unique_id=l8{zqkNJ$enMUpveb:oDj5[}^x)_V{,q # nfs4_unique_id が指定されたことを確認する $ cat /etc/modprobe.d/nfsclient.conf options nfs nfs4_unique_id=l8{zqkNJ$enMUpveb:oDj5[}^x)_V{,q # OSの再起動 $ sudo systemctl reboot Terminated
再起動後、NFS v4でマウントできているか確認します。
# FSx for ONTAPのボリュームをNFSでマウントしているか確認 $ df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 471M 0 471M 0% /dev tmpfs tmpfs 479M 0 479M 0% /dev/shm tmpfs tmpfs 479M 352K 478M 1% /run tmpfs tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/nvme0n1p1 xfs 8.0G 1.7G 6.4G 21% / svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs nfs4 973M 384K 973M 1% /mnt/fsx # マウントオプションを確認 $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime) svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs on /mnt/fsx type nfs4 (rw,relatime,vers=4.1,rsize=65536,wsize=65536,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.1.10,local_lock=none,addr=10.0.1.20,_netdev) # ホスト名が ec2-instance.corp.non-97.net であることを確認 $ hostname ec2-instance.corp.non-97.net # EC2インスタンス AのIPアドレスであることを確認 $ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000 link/ether 0e:84:4c:2f:e6:3b brd ff:ff:ff:ff:ff:ff inet 10.0.1.10/28 brd 10.0.1.15 scope global dynamic eth0 valid_lft 3481sec preferred_lft 3481sec inet6 fe80::c84:4cff:fe2f:e63b/64 scope link valid_lft forever preferred_lft forever # nfs4_unique_id が指定されていることを確認 $ sudo systool -v -m nfs | grep -i nfs4_unique nfs4_unique_id = "l8{zqkNJ$enMUpveb:oDj5[}^x)_V{,q"
ホスト名が同じでもNFS v4でマウントできることを確認できました。
Auto Scalingの場合は、以下コマンドを起動設定のユーザーデータで行えばよさそうです。
nfs4_unique_id=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9!@#$%^&*()_+-=[]{}<>?' | fold -w 32 | head -n 1) echo options nfs nfs4_unique_id="$nfs4_unique_id" >> /etc/modprobe.d/nfsclient.conf systemctl reboot
なお、今回は32桁のランダムな文字列をnfs4_unique_id
に設定しましたが、お好みでfold -w 32
の数字を変更して、64桁や128桁などに変更してください。
EC2インスタンス Bのマウントの状態も確認しておきましょう。
# EC2インスタンス Bでも引き続きマウントできていることを確認 $ df -hT Filesystem Type Size Used Avail Use% Mounted on devtmpfs devtmpfs 471M 0 471M 0% /dev tmpfs tmpfs 479M 0 479M 0% /dev/shm tmpfs tmpfs 479M 408K 478M 1% /run tmpfs tmpfs 479M 0 479M 0% /sys/fs/cgroup /dev/nvme0n1p1 xfs 8.0G 1.7G 6.4G 21% / tmpfs tmpfs 96M 0 96M 0% /run/user/0 svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs nfs4 973M 384K 973M 1% /mnt/fsx # マウントオプションを確認 $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime) svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs on /mnt/fsx type nfs4 (rw,relatime,vers=4.1,rsize=65536,wsize=65536,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.1.13,local_lock=none,addr=10.0.1.20,_netdev)
一度アンマウントして、再マウントも試してみます。
# アンマウント $ sudo umount /mnt/fsx # アンマウントされたことを確認 $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime) # 再マウント $ sudo mount -a # 再マウントできたことを確認 $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime) svm-094f0cf75b091424e.fs-013816ec87fee14ad.fsx.us-east-1.amazonaws.com:/nfs on /mnt/fsx type nfs4 (rw,relatime,vers=4.1,rsize=65536,wsize=65536,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.1.13,local_lock=none,addr=10.0.1.20,_netdev)
マウントできますね。
ちなみに当然ですが、nfs4_unique_id
が重複するとマウントできません。
# EC2インスタンス Aの nfs4_unique_id と同じ文字列を nfs4_unique_id に設定 $ echo options nfs nfs4_unique_id='l8{zqkNJ$enMUpveb:oDj5[}^x)_V{,q' | sudo tee -a /etc/modprobe.d/nfsclient.conf options nfs nfs4_unique_id=l8{zqkNJ$enMUpveb:oDj5[}^x)_V{,q $ cat /etc/modprobe.d/nfsclient.conf options nfs nfs4_unique_id=l8{zqkNJ$enMUpveb:oDj5[}^x)_V{,q # 設定を反映させるためにOSを再起動 $ sudo systemctl reboot Terminated [再起動後] # マウントされていないことを確認 $ mount | grep nfs sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime) # EC2インスタンス Aの nfs4_unique_id と同じ文字列が nfs4_unique_id に設定されていることを確認 $ sudo systool -v -m nfs | grep -i nfs4_unique nfs4_unique_id = "l8{zqkNJ$enMUpveb:oDj5[}^x)_V{,q"
Auto Scalingするときは特に注意
クライアントのホスト名が重複しているとNFS v4でAmazon FSx for NetApp ONTAPのボリュームをマウントできない事象を紹介しました。
特に、Auto Scalingをするときにはどハマりすること間違い無いです。NFS v4で接続できない場合は各EC2インスタンスのホスト名を変更するか、一意なnfs4_unique_id
を設定して再チャレンジしてみてください。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!